package ce.com.cenewbluesdk.proxy;


import android.content.Context;
import android.os.Message;
import android.util.Log;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import ce.com.cenewbluesdk.CEBC;
import ce.com.cenewbluesdk.bluetooth.CEBlueTooth_4;
import ce.com.cenewbluesdk.connect.ReconnectModeA;
import ce.com.cenewbluesdk.entity.CEDevData;
import ce.com.cenewbluesdk.entity.k2.K2_Action;
import ce.com.cenewbluesdk.entity.k2.K2_HeartStruct;
import ce.com.cenewbluesdk.entity.k2.K2_MusicInfo;
import ce.com.cenewbluesdk.entity.k2.K2_SendContacts;
import ce.com.cenewbluesdk.entity.k2.K2_CESyncTime;
import ce.com.cenewbluesdk.entity.k2.K2_DevInfoStruct;
import ce.com.cenewbluesdk.entity.k2.K2_MessageNoticeStruct;
import ce.com.cenewbluesdk.entity.k2.K2_MixInfoStruct;
import ce.com.cenewbluesdk.entity.k2.K2_SendAlarmInfoStruct;
import ce.com.cenewbluesdk.entity.k2.K2_SendDevSettingStruct;
import ce.com.cenewbluesdk.entity.k2.K2_SendGoal;
import ce.com.cenewbluesdk.entity.k2.K2_SendUserInfo;
import ce.com.cenewbluesdk.entity.k2.K2_SendWeatherStruct;
import ce.com.cenewbluesdk.entity.k2.K2_Send_Watch_Face_And_Notification_Set;
import ce.com.cenewbluesdk.entity.k2.K2_SendNote;
import ce.com.cenewbluesdk.entity.k2.K2_Sport;
import ce.com.cenewbluesdk.entity.k3.Send_Alarm_Info_Struct_K3;
import ce.com.cenewbluesdk.entity.k6.K6_HeartStruct;
import ce.com.cenewbluesdk.queue.CEProtocolB;
import ce.com.cenewbluesdk.uitl.ByteUtil;
import ce.com.cenewbluesdk.uitl.CRC16;
import ce.com.cenewbluesdk.uitl.Lg;


/**
 * Created by Administrator on 2016/11/9 0009.
 */
public class CEDevK2Proxy extends CEBluetoothProxyBase {

    public static final String UUID = "0000cc68-0000-1000-8000-00805f9b34fb";

    public static final int devType = 5;

    SendHelper sendHelper = new SendHelper();


    protected CEDevK2Proxy(Context context) {
        super(context);
    }


    public SendHelper getSendHelper() {
        return sendHelper;
    }


    @Override
    protected void dataSendSucceed(CEDevData devData) {
        dealSendResult(devData,K2_Action.SEND_R.DATA_SEND_SUCCESS);
    }

    @Override
    protected void DataSendFailed(CEDevData devData) {
        dealSendResult(devData,K2_Action.SEND_R.DATA_SEND_FAIL);
    }

    @Override
    protected void receiptData(CEDevData devData) {
        analysisCEDevData(devData);
    }

    @Override
    protected void blueToothConnectStateChange(int state) {
        sendMeg(createMessage(CEBC.BLUE_CONNECT_STATE_CHANGE, state));
        if (state == CEBC.BLUE_CONNECTED) {
//            getSendHelper().sendTime();
            // 需要用延时发送。
        }
    }

    @Override
    protected void initProxy() {
        blueTooth = new CEBlueTooth_4(context, UUID);
        connectUtil = new CEConnectUtil(context, new ReconnectModeA(), this, blueTooth);
        devQueue = new CEDevQueue(this, new CEProtocolB(devType), blueTooth);
    }

    @Override
    protected String getClassName() {
        return "CEDevK2Proxy";
    }


    private void analysisCEDevData(CEDevData ceDevData) {
        Lg.e("收到完整的数据：" + ceDevData.toString());
        byte[] payload = null;
        switch (ceDevData.getDataType()) {
            case CEBC.K2.DATA_TYPE_DEVINFO:
                dealDevInfo(ceDevData.getData());
                break;
            case CEBC.K2.DATA_TYPE_BATTERY_INFO:
                dealRcvdBattery(ceDevData.getData());
                break;
            case CEBC.K2.DATA_TYPE_ALARM:
                payload = ceDevData.getData();
                dealGetAlarm(payload);
                break;
            case CEBC.K2.DATA_TYPE_DEV_SYNC:
                payload = ceDevData.getData();
                if (payload != null && payload.length > 0) {
                    K2_MixInfoStruct result = K2_MixInfoStruct
                            .parse(payload);
                    for (K2_MixInfoStruct.Property property : result.getList()) {
                        switch (property.getDate_type()) {
                            case CEBC.K2.DATA_TYPE_ALARM://闹钟
                                dealGetAlarm(property.getData());
                                Lg.e("闹钟:" + Arrays.toString(property.getData()));
                                break;
                            case CEBC.K2.DATA_TYPE_SETTING://设备设置信息
                                dealGetSetting(property.getData());
                                Lg.e("设备设置信息:" + Arrays.toString(property.getData()));
                                break;
                            case CEBC.K2.DATA_TYPE_DEVINFO://设备信息
                                dealDevInfo(property.getData());
                                Lg.e("设备信息:" + Arrays.toString(property.getData()));
                                break;
                            case CEBC.K2.DATA_TYPE_BATTERY_INFO://电池电量信息
                                dealRcvdBattery(property.getData());
                                Lg.e("电池电量信息:" + Arrays.toString(property.getData()));
                                break;
                            case CEBC.K2.DATA_TYPE_WATCHFACE_MENU_SELECT://16 表盘、通知开关、Workout 设置信息
                                dealWacthFace_Notification_workout(property.getData());
                                Lg.e("表盘设置:" + CEBC.byte2hex(property.getData()));
//                            Log.d("liu", "电池电量信息:" + Arrays.toString(property.getData()));
                                break;
                            case CEBC.K2.DATA_TYPE_OTA_STATUS:
//                         OTA  不需要处理
                                Lg.e("OTA 信息");
                                break;
                        }
                    }
                    //            sendPmessage(BC.CMD.ACTION_OBTAIN_DEVINFO_SUCCESS.hashCode(), dev_Info_Struct);
                }
                break;
            case CEBC.K2.DATA_TYPE_HISTORY_SPORT: // 历史运动数据
                dealSportData(ceDevData);
                break;
            case CEBC.K2.DATA_TYPE_REAL_SPORT: // 实时运动数据
                dealSportData(ceDevData);
                break;
            case CEBC.K2.DATA_TYPE_PHOTOGRAPH:
                lge("接收到了拍照的命令");
                break;
            case CEBC.K2.DATA_TYPE_MUSIC_CONTROL:
                lge("接收到了音乐控制的命令："+ceDevData.getData()[0]);
                if(ceDevData.getData()[0]==6){
                    getSendHelper().sendMusicInfo(new K2_MusicInfo(1,"abc","abcdefghijklmnopqrstuvwsyz","abcdefghijklmnopqrstuvwsyz"));
                }
                break;
            case CEBC.K2.DATA_TYPE_HISTORY_HEART:
                lge("DATA_TYPE_HISTORY_HEART");
                dealHeart(ceDevData);
                break;
            case CEBC.K2.DATA_TYPE_REAL_HEART:
                lge("DATA_TYPE_HISTORY_HEART");
                dealHeart(ceDevData);
                break;

        }


    }


    public class SendHelper {
        public void sendUserInfo(K2_SendUserInfo userInfoK2) {
            devQueue.push(userInfoK2.toCEDevData());
        }

        public void sendTime() {
            K2_CESyncTime time = K2_CESyncTime.getCurrentTime();
            devQueue.push(time.toCEDevData());
        }

        public void sendSetting(K2_SendDevSettingStruct settingStructK2) {
            devQueue.push(settingStructK2.toCEDevData());
        }

        public void getDevInfo() {
            CEDevData data = new CEDevData();
            data.setCmd(CEBC.K2.CMD_TYPE_REQUEST);
            data.setDataType(CEBC.K2.DATA_TYPE_DEVINFO);
            devQueue.push(data);
        }

        /**
         * 发送闹钟设置信息
         */
        public void sendAlarmInfo(
                ArrayList<K2_SendAlarmInfoStruct> alarm_Info_Structs) {
//            if (alarm_Info_Structs == null || alarm_Info_Structs.size() == 0)
//                return;
            byte[] payload = new byte[K2_SendAlarmInfoStruct.getItemSize() * alarm_Info_Structs.size() + 1];
            Lg.e("发送闹钟设置信息,共" + alarm_Info_Structs.size() + "组闹钟");
            payload[0] = (byte) alarm_Info_Structs.size();
            for (int i = 0; i < alarm_Info_Structs.size(); ++i) {
                K2_SendAlarmInfoStruct this_alrm = alarm_Info_Structs.get(i);
                byte[] this_alarm_payload = this_alrm.getBytes();
                System.arraycopy(this_alarm_payload, 0, payload, i * K2_SendAlarmInfoStruct.getItemSize() + 1, K2_SendAlarmInfoStruct.getItemSize());
            }
            Lg.e("发送闹钟设置信息,payload : " + Arrays.toString(payload));
            CEDevData data = new CEDevData();
            data.setCmd(CEBC.K2.CMD_TYPE_SEND);
            data.setDataType(CEBC.K2.DATA_TYPE_ALARM);
            data.setItemL(payload.length);
            data.setData(payload);
            data.setItemNumber(1);
            devQueue.push(data);
        }

        /**
         * 短信通知信息
         */
        public void sendMessage_notice(
                long time, String name, String content, byte messageType) {
            if (name == null || content == null) {
                return;
            }
            Log.e("liu", "短信发送给设备侧了  。");
            K2_MessageNoticeStruct msg = new K2_MessageNoticeStruct(time, messageType);
            msg.setSendContext(name, K2_MessageNoticeStruct.Property.TYPE_CONTENT, content);

            sendMessage_notice(msg);
        }


        public void sendMessage_notice(K2_MessageNoticeStruct msg) {
            devQueue.push(msg.toCEDevData());
        }

        /**
         * 发送天气信息
         *
         * @param weatherStruct
         */
        public void sendWeatherInfo(K2_SendWeatherStruct weatherStruct) {
            devQueue.push(weatherStruct.toCEDevData());
        }


        /**
         * 获取混合数据
         */
        public void getMixInfo() {
            CEDevData data = new CEDevData();
            data.setCmd(CEBC.K2.CMD_TYPE_REQUEST);
            data.setDataType(CEBC.K2.DATA_TYPE_DEV_SYNC);

            devQueue.push(data);
        }

        /**
         * 发送混杂数据
         *
         * @param mixinfo
         */
        public void sendMixInfo(K2_MixInfoStruct mixinfo) {
            byte[] payload = mixinfo.getBytes();
            CEDevData data = new CEDevData();
            data.setCmd(CEBC.K2.CMD_TYPE_SEND);
            data.setDataType(CEBC.K2.DATA_TYPE_APP_SYNC);
            data.setItemL(payload.length);
            data.setItemNumber(1);
            data.setData(payload);
            devQueue.push(mixinfo.toCEDevData());
        }

        /**
         * 设置gesensor数据传输开关
         */
        public void setEnableGsDataTrans(boolean enable) {
            CEDevData data = new CEDevData(CEBC.K2.CMD_TYPE_SEND, CEBC.K2.DATA_TYPE_SET_DATA_SWITCH);
            data.setData(new byte[]{(byte) (enable ? 1 : 0)});
            devQueue.push(data);
        }

        /**
         * 设置目标
         */
        public void sendGoal(K2_SendGoal enable) {

            devQueue.push(enable.toCEDevData());
        }

        /**
         * 发送配对
         */
        public void sendPairFinish(boolean isok) {
            CEDevData data = new CEDevData(CEBC.K2.CMD_TYPE_SEND, CEBC.K2.DATA_TYPE_PAIR_FINISH);
            byte[] bytes = new byte[2];
            bytes[0] = (byte) (isok ? 1 : 0);
            bytes[1] = (byte) 0;
            data.setData(bytes);
            devQueue.push(data);
        }

        /**
         * 发送表盘通知等设置
         */
        public void sendWatchFace(K2_Send_Watch_Face_And_Notification_Set set) {
            devQueue.push(set.toCEDevData());
        }

        /**
         * 发送日历的提醒数据
         */
        public void send_Note(K2_SendNote send_note) {

            CEDevData cedata = new CEDevData(CEBC.K2.CMD_TYPE_SEND, CEBC.K2.DATA_TYPE_NOTE_REMIND);
            byte[] bytes = new byte[send_note.getSendbyte().length + 1];
            System.arraycopy(send_note.getSendbyte(), 0, bytes, 1, send_note.getSendbyte().length);
            bytes[0] = 1;
            cedata.setData(bytes);
            cedata.setItemNumber(1);
            cedata.setItemL(send_note.getSendbyte().length);
            devQueue.push(cedata);


        }


        /**
         * 发送名片
         */
        public void sendUserCard(CEDevData cedata) {
            devQueue.push(cedata);
        }


        /**
         * 发送联系人
         */
        public void sendPhoneBook(ArrayList<K2_SendContacts> contactses, int index) {
            if (index >= contactses.size()) {
                return;
            }
            byte[] date;
            int sendL;
            if (index + 6 < contactses.size()) {
                sendL = 6;
            } else {
                sendL = (contactses.size() - index);
            }
            date = new byte[sendL * 40];
            for (int i = index; i < index + 6 && i < contactses.size(); i++) {
                System.arraycopy(contactses.get(i).getbyte(), 0, date, (i - index) * 40, contactses.get(i).getbyte().length);
            }
            CEDevData ceDevData = new CEDevData(CEBC.K2.CMD_TYPE_SEND, CEBC.K2.DATA_TYPE_PHONE_BOOK_DOWN);
            byte[] sendData = new byte[5 + date.length];

            System.arraycopy(ByteUtil.int2bytes2(index), 0, sendData, 0, 2);
            System.arraycopy(ByteUtil.int2bytes2(contactses.size()), 0, sendData, 2, 2);
            sendData[4] = (byte) sendL;
            System.arraycopy(date, 0, sendData, 5, date.length);
            ceDevData.setItemNumber(1);
            ceDevData.setItemL(5 + date.length);
            ceDevData.setData(sendData);
            devQueue.push(ceDevData);
        }


        /**
         * 发送音乐信息
         */
        public void sendMusicInfo(K2_MusicInfo enable) {
            devQueue.push(enable.toCEDevData());
        }

        /**
         * 发送分包
         *
         * @param arg 每一个分包
         */
        public void sendGpsArgument(byte[] arg){
            CEDevData ceDevData = new CEDevData();
            ceDevData.setCmd(CEBC.K2.CMD_TYPE_SEND);
            ceDevData.setData(arg);
            ceDevData.setDataCrc16(CRC16.crc16(arg));
            ceDevData.setDataType(CEBC.K2.DATA_TYPE_GPS_ARGUMENT);
            ceDevData.setItemL(arg.length);
            devQueue.push(ceDevData);
        }

    }

    private void dealSendResult(CEDevData ceDevData, int result) {
        Message message=null;
        switch (ceDevData.getDataType()) {
            case CEBC.K2.DATA_TYPE_ALARM:
                message = createMessage(K2_Action.SEND_R.SEND_ALARM.hashCode(), result);
                break;
            case CEBC.K2.DATA_TYPE_SET_TARGET:
                message = createMessage(K2_Action.SEND_R.SEND_DEV_GOAL.hashCode(), result);
                break;
            case CEBC.K2.DATA_TYPE_WEATHER:
                message = createMessage(K2_Action.SEND_R.SEND_WEATHER_STRUCT.hashCode(), result);
                break;
            case CEBC.K2.DATA_TYPE_WATCHFACE_MENU_SELECT:
                message = createMessage(K2_Action.SEND_R.SEND_WATCH_FACE_AND_NOTIFICATION_SET.hashCode(), result);
                break;
            case CEBC.K2.DATA_TYPE_MESSAGE_NOTICE:
                message = createMessage(K2_Action.SEND_R.SEND_MESSAGE_NOTICE.hashCode(), result);
                break;
            case CEBC.K2.DATA_TYPE_SETTING:
                message = createMessage(K2_Action.SEND_R.SEND_DEV_SET.hashCode(), result);
                break;
            case CEBC.K2.DATA_TYPE_TIME:
                message = createMessage(K2_Action.SEND_R.SEND_TIME.hashCode(), result);
                break;
            case CEBC.K2.DATA_TYPE_USERINFO:
                message = createMessage(K2_Action.SEND_R.SEND_USER_INFO.hashCode(), result);
                break;
            case CEBC.K2.DATA_TYPE_SET_DATA_SWITCH:
                message = createMessage(K2_Action.SEND_R.SEND_DATA_SWITCH.hashCode(), result);
                break;
            case CEBC.K2.DATA_TYPE_GPS_ARGUMENT:
                message = createMessage(K2_Action.SEND_R.SEND_DATA_GPS_ARGUMENT.hashCode(),result);
                break;
        }
        if(message!=null){
            sendMeg(message);
        }


    }


    /**
     * 处理获取到的闹钟信息
     *
     * @param payload
     */
    private void dealGetAlarm(byte[] payload) {
        int num = payload[0];
        ArrayList<Send_Alarm_Info_Struct_K3> alarm_info_struct_k3s = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            int alarmFirstIndex = i * 4 + 1;
            alarm_info_struct_k3s.add(new Send_Alarm_Info_Struct_K3(payload[alarmFirstIndex],
                    payload[alarmFirstIndex + 1], payload[alarmFirstIndex + 2], payload[alarmFirstIndex + 3]));

        }
        for (Send_Alarm_Info_Struct_K3 a :
                alarm_info_struct_k3s) {
            Lg.e(a.toString() + "\n");
        }
        sendMeg(createMessage(K2_Action.RCVD.RCVD_ALARM.hashCode(), alarm_info_struct_k3s));
    }

    /**
     * 处理设备传过来的设置信息
     *
     * @param payload
     */
    private void dealGetSetting(byte[] payload) {
//            if (payload != null && payload.length == Send_Dev_Setting_Struct_K3.getItemSize()) {
        if (payload != null) {
            byte[] devInfo = new byte[K2_SendDevSettingStruct.getItemSize()];
            System.arraycopy(payload, 0, devInfo, 0,
                    K2_SendDevSettingStruct.getItemSize());
            K2_SendDevSettingStruct setting = new K2_SendDevSettingStruct(devInfo);
            Log.d("rd65", "设备设置信息" + setting.toString());
            sendMeg(createMessage(K2_Action.RCVD.RCVD_DEV_SET.hashCode(), setting));
        }
    }

    /**
     * /16 表盘、通知开关、Workout 设置信息
     *
     * @param payload
     */
    private void dealWacthFace_Notification_workout(byte[] payload) {
//            if (payload != null && payload.length == Send_Watch_Face_And_Notification_Set_K3.getItemSize()) {
        if (payload != null) {
            byte[] info = new byte[K2_Send_Watch_Face_And_Notification_Set.getItemSize()];
            System.arraycopy(payload, 0, info, 0,
                    K2_Send_Watch_Face_And_Notification_Set.getItemSize());
            K2_Send_Watch_Face_And_Notification_Set setting = new K2_Send_Watch_Face_And_Notification_Set(info);
            sendMeg(createMessage(K2_Action.RCVD.RCVD_WATCH_FACE_AND_NOTIFICATION_SET.hashCode(), setting));
        }

    }

    /**
     * 处理获取到的设备信息
     *
     * @param payload
     */
    private void dealDevInfo(byte[] payload) {
        byte[] devInfo = new byte[K2_DevInfoStruct.devInfoByteLen];
        System.arraycopy(payload, 0, devInfo, 0,
                K2_DevInfoStruct.devInfoByteLen);
        K2_DevInfoStruct dev_Info_Struct = K2_DevInfoStruct
                .parseDevInfo(devInfo);
        Log.d("rd65", "设备信息" + dev_Info_Struct.toString());
        sendMeg(createMessage(K2_Action.RCVD.RCVD_DEVINFO.hashCode(), dev_Info_Struct));
    }

    /**
     * 处理电池信息
     *
     * @param payload
     */
    private void dealRcvdBattery(byte[] payload) {
        if (payload != null) {
            Log.d("rd65", "电池信息" + payload[0]);
            sendMeg(createMessage(K2_Action.RCVD.RCVD_BATTERY.hashCode(), payload[0]));
        }
    }

    private  void dealHeart(CEDevData ceDevData) {
        lge("接收到了心率数据");

        byte[] payload = ceDevData.getData();
        if (payload != null && payload.length > 0) {
            ArrayList<K2_HeartStruct> list = K2_HeartStruct.parse(payload);
            sendMeg(createMessage(K2_Action.RCVD.RCVD_HEART.hashCode(),list));
        }


    }

    /**
     * 处理运动数据
     */
    private void dealSportData(CEDevData devData) {
        byte[] datas = devData.getData();
        int allItem = ByteUtil.byte2ToInt(new byte[]{datas[0], datas[1]});
        int item = datas[2];
        int index = 3;

        if (item * K2_Sport.getItemSize() != datas.length - 3) {
            Lg.e("运动数据长度和item数对不上" + (datas.length - 3) + "item ：" + item);
            return;
        }

        ArrayList<K2_Sport> sports = new ArrayList<>();
        for (int i = 0; i < item; i++) {
            byte[] sprotData = new byte[K2_Sport.getItemSize()];
            System.arraycopy(datas, index, sprotData, 0, K2_Sport.getItemSize());
            sports.add(new K2_Sport(sprotData));
            index += K2_Sport.getItemSize();
        }
        Message message = createMessage(K2_Action.RCVD.RCVD_SPORT_DAT.hashCode(), sports);
        message.getData().putInt("allItem", allItem);
        message.getData().putInt("item", item);
        sendMeg(message);
    }

    public static void lge(String log) {
        Lg.e("k2", log);
    }
}
